package cn.jtfadmin.base.filesystem.config;

import org.springframework.beans.factory.ObjectProvider;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.*;

public abstract class BaseFileSystemImpl implements FileSystem {


    public BaseFileSystemImpl(ObjectProvider<FileResourceConfig> fileResourceConfigListOptional) {
        for (FileResourceConfig fileResourceConfig : fileResourceConfigListOptional) {
            registerFileResourceConfig(fileResourceConfig);
        }
    }


    /**
     * 注册文件配置
     *
     * @param fileResourceConfig 文件配置
     */
    protected abstract void registerFileResourceConfig(FileResourceConfig fileResourceConfig);


    /**
     * 获取所有的文件配置
     *
     * @return
     */
    protected abstract List<FileResourceConfigDTO> getAllFileConfig();

    /**
     * 复制本地文件后删除本地文件文件
     *
     * @param source   本地源文件
     * @param fileType 复制到的文件类型
     * @return 文件相对url
     */
    @Override
    public String copyFileAndDelSource(Path source, String fileType) {
        String fileName = source.toFile().getName();
        String ext = fileName.substring(fileName.lastIndexOf(".") + 1);// 后缀
        try {
            return upload(Files.newInputStream(source), fileType, ext);
        } catch (IOException e) {
            throw new RuntimeException(e);
        } finally {
            try {
                Files.deleteIfExists(source);
            } catch (IOException e) {
                // ignore
            }
        }
    }


    /**
     * 上传spring web文件
     *
     * @param file 文件
     * @param type 文件类型
     * @return 文件名
     */
    @Override
    public String upload(MultipartFile file, String type, boolean updateFileName) {
        String originalFilename = file.getOriginalFilename();
        String ext = originalFilename.substring(originalFilename.lastIndexOf(".") + 1);
        try {
            if(updateFileName){
                return upload(file.getInputStream(), type, ext);
            }else {
                return upload(type,file.getInputStream(),originalFilename);
            }

        } catch (IOException e) {
            throw new RuntimeException(e);
        }


    }


    /**
     * 获取类型配置后缀
     *
     * @param type 类型
     * @return
     */
    @Override
    public List<String> getTypeSuffix(String type) {
        Optional<FileResourceConfigDTO> first = getAllFileConfig().stream().filter(t -> Objects.equals(t.getDir(), type))
                .findFirst();
        if (first.isPresent()) {
            return Arrays.asList(first.get().getFileType().getAllowedExtension());
        }
        return Collections.emptyList();
    }


    /**
     * 验证类型是否存在
     *
     * @param type 类型
     * @return true 存在，false 不存在
     */
    @Override
    public boolean validType(String type) {
        return getAllFileConfig().stream().anyMatch(t -> Objects.equals(t.getDir(), type));
    }


    /**
     * 验证重复项
     *
     * @param fileResourceConfig 文件配置
     * @param list               文件配置列表
     * @return 和本类重复的配置
     */
    protected List<FileResourceConfigDTO> validateRepeate(FileResourceConfigDTO fileResourceConfig, List<FileResourceConfigDTO> list) {
        List<FileResourceConfigDTO> remove = new LinkedList<>();
        for (FileResourceConfigDTO resourceConfig : list) {
            if (resourceConfig == fileResourceConfig) {
                continue;
            }
            if (Objects.equals(fileResourceConfig.getDir(), resourceConfig.getDir())) {
                if (Objects.equals(fileResourceConfig.getDescribe(), resourceConfig.getDescribe())
                        && Objects.equals(fileResourceConfig.getFileType(), resourceConfig.getFileType())
                ) {
                    remove.add(resourceConfig);
                } else {
                    throw new RuntimeException("文件类型注册,dir:" + resourceConfig.getDir() + " 重复");
                }
            }
        }
        return remove;
    }


    @Override
    public String getFileName(String fileRelativeUrl) {
        return fileRelativeUrl.substring(fileRelativeUrl.lastIndexOf("/") +1 );
    }
}
